# Copyright (c) 2009 by Alex Leone <acleone ~at~ gmail.com>
#
# This file is part of epp.
#
# epp is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# epp is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with epp.  If not, see <http://www.gnu.org/licenses/>.

r"""
Contains the [compile] tag.

Syntax:
    [compile tagname:]
        Python code, saving output to the variable `output'.
        eg output = "this is my replacement"

Attributes:
    -- name: the tagname to store this tag as.  eg call the tag with
             `[tagname]'
    -- 'replace' (no value): replace

Outputs:
    The [compile] tag itself will return ''
    The tag defined by compile, `[tagname]', returns the value of the
    variable `output', or '' if output is never assigned a value

Examples:
    Note: s[1:] in p.parsetags(s[1:]) is to strip the leading '\n'
          from s

    >>> import epp
    >>> p = epp.Epp()
    >>> s = '''
    ... [compile tag1:]
    ...  output = 'Hello World!'
    ... [tag1]'''
    >>> print(p.parsetags(s[1:]))
    Hello World!
    >>> s = '''
    ... [compile tag2:]
    ...  "Oops, I forgot to set output!"
    ... [tag2]'''
    >>> print(p.parsetags(s[1:]))
    <BLANKLINE>
    >>> s = '''
    ... [compile tag3:]
    ...  output = "[%s tag3:]%c %s%c[%s]" % ("compile", 10, self.code, 10, "tag3")
    ... [tag3]'''
    >>> print(p.parsetags(s[1:]))
    [compile tag3:]
     output = "[%s tag3:]%c %s%c[%s]" % ("compile", 10, self.code, 10, "tag3")
    [tag3]
"""

import tags
from tags.tag import Tag

tagnames = ["compile"]

class CompiledTag(Tag):
    """
    Compiled tag created by compile
    """

    def __init__(self, tagName, code):
        self.tagName = tagName
        self.code = code

    def replace(self, eppinst, tagName, attrs):
        """
        Save output to variable `output`
        """
        parsedcode = eppinst.parsetags(self.code)
        output = ''
        exec(compile(parsedcode, "<string>", "exec"))
        return output

class Compile(Tag):

    def replace(self, eppinst, tagName, attrs):
        """
        The compile tag.  name="statements".
        See the python compile function.
        save output to the variable `output`.
        """
        replaceSeen = False
        for attrName, value in attrs:
            if attrName == 'replace' and value == None:
                replaceSeen = True
                continue
            if (not replaceSeen) and attrName in eppinst._tags:
                    eppinst._print_message(
                            "Warning: [%s] redefinition of %r"
                            % (tagName, attrName), 1)
            newF = CompiledTag(attrName, value)
            eppinst._tags[attrName] = newF
            replaceSeen = False
        return ''